
module Distribution.Common where

import qualified Numeric.Probability.Distribution as Dist
import Control.Monad

type Dist = Dist.T Double Double

foldDist :: (Num a, Ord b)=>Int->Dist.T a b->Dist.T a b
foldDist n d 
        | n>1   = liftM2 max d (foldDist (n-1) d)
        | n<=1  = d 


foldOnce d = liftM2 max d d

foldHour :: (Num a, Ord b)=>Dist.T a b->Dist.T a b
foldHour = foldDist 60

foldDay :: (Num a, Ord b)=>Dist.T a b->Dist.T a b
foldDay  = foldDist 3600

-- h, l and sl
data BracketStrategy = Bracket Double Double Double
        deriving (Show)

-- Let say that we've got 2 distributions: up and down distribution for given day
-- We've got 3 possible outcomes of bracket strategy:
--  1. If price was in range of (h+sl)..h and l..(l+sl), then we earn h+l (twice)
--  2. If price was higher than h+sl, we loose sl
--  3. If price was lower than l+sl, we loose sl
--  4. If price was in range h..l, then we might earn something but put it to zero.
-- So we've got lPdf and hPdf as of Dist

-- naive approach

func :: BracketStrategy->Double->Double->Double
func (Bracket h l sl) hp lp
        | (h+sl)>hp && h<=hp && l<=lp && (l+sl)>lp      = 2*(h+l)
        | hp > (h+sl)                                   = -sl
        | lp > (h+sl)                                   = -sl
        | otherwise                                     = 0.0

outcomePdf :: Dist->Dist->BracketStrategy->Dist
outcomePdf hpdf lpdf bracket = liftM2 (func bracket) hpdf lpdf
